package com.jsbs.iam.ident.controller;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.jsbs.iam.common.core.dto.Result;
import com.jsbs.iam.common.core.utils.StringUtils;
import com.jsbs.iam.ident.constant.Constants;
import com.jsbs.iam.ident.dto.*;
import com.jsbs.iam.ident.entity.IamBlacklistManagement;
import com.jsbs.iam.ident.entity.IamExceptionLoginStrategy;
import com.jsbs.iam.ident.entity.IamLoginStrategy;
import com.jsbs.iam.ident.entity.IamMultideviceStrategy;
import com.jsbs.iam.ident.feign.IdentFeignInter;
import com.jsbs.iam.ident.param.UserQueryParam;
import com.jsbs.iam.ident.service.IIamPasswordStrategyService;
import com.jsbs.iam.ident.service.IamExceptionLoginStrategyService;
import com.jsbs.iam.ident.service.IamMultiDeviceStrategyService;
import com.jsbs.iam.ident.vo.*;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhouxiangyang
 * @className IamStrategyController
 * @date 2022/12/15 11:08
 * @description: 策略管理Controller
 */
@RestController
@RequestMapping("/iam/ident/strategy")
public class IamStrategyController extends BaseController{


    @Autowired
    private IIamPasswordStrategyService iamPasswordStrategyService;

    @Autowired
    private IamExceptionLoginStrategyService iamExceptionLoginStrategyService;

    @Autowired
    private IdentFeignInter identFeignInter;

    @Autowired
    private IamMultiDeviceStrategyService iamMultiDeviceStrategyService;

    private static final Logger logger = LoggerFactory.getLogger(IamStrategyController.class);

    /**
     * 全量查询密码策略并进行默认分页（每页十条）
     * @param
     * @return
     */
    @RequestMapping("/getIamPasswordStrategyPage")
    public Result getIamPasswordStrategyPage (@RequestBody PasswordStrategySearchDto passwordStrategySearchDto,
                                              HttpServletRequest request){
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        PageInfo<IamPasswordStrategyVo> iamPasswordStrategyList
                = iamPasswordStrategyService.getIamPasswordStrategyList(passwordStrategySearchDto,companyCode);
       return Result.success(iamPasswordStrategyList);
    }

    /**
     * 批量删除密码策略
     * @param strategyCodeList
     * @return
     */
    @RequestMapping("/deleteBatchStrategyCode")
    public Result deleteBatchStrategyCode (@RequestBody List<String> strategyCodeList,
                                           HttpServletRequest request) {
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        //批量删除策略
        int i = iamPasswordStrategyService.deleteBatchStrategyCode(strategyCodeList,companyCode);
        if (i == 0){
            Result.failWithMsg("删除密码策略失败");
        }
       return Result.success("删除密码策略成功",i);
    }

    /**
     * 新增密码策略
     * @param iamPasswordStrategyDto
     * @return
     */
    @RequestMapping("/saveIamPasswordStrategy")
    public Result saveIamPasswordStrategy (@RequestBody IamPasswordStrategyDto iamPasswordStrategyDto,
                                           HttpServletRequest request) {
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        iamPasswordStrategyDto.setCompanyCode(companyCode);
        int i = 0;
        try {
            //新增密码策略
            i = iamPasswordStrategyService.saveIamPasswordStrategy(iamPasswordStrategyDto);
        } catch (Exception e) {
            logger.error("新增密码策略错误，信息为：{}", e);
            return handleException(e,e.getMessage());
        }
        if (i == 0){
            return Result.failWithMsg("未能成功新增密码策略");
        }
        return  Result.success("新增密码策略成功",i);
    }

    /**
     * 编辑密码策略
     * @param iamPasswordStrategyDto
     * @return
     */
    @RequestMapping("/updateIamPasswordStrategy")
    public Result updateIamPasswordStrategy (@RequestBody IamPasswordStrategyDto iamPasswordStrategyDto,
                                             HttpServletRequest request){
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        iamPasswordStrategyDto.setCompanyCode(companyCode);
        int i = 0;
        try {
            //编辑策略
            i = iamPasswordStrategyService.updateIamPasswordStrategy(iamPasswordStrategyDto);
        } catch (Exception e) {
            logger.error("更新密码策略错误，信息为：{}", e);
            return handleException(e,e.getMessage());
        }
        if (i == 0){
            return Result.failWithMsg("策略未能更新成功");
        }
        return Result.success("策略更新成功",i);
    }

    /**
     * 应用下拉列表
     * @return
     */
    @RequestMapping("/getApplySystemAll")
    public Result<List<String>> getApplySystemAll () {
        Result<List<String>> applySystemAll = null;
        try {
            applySystemAll = identFeignInter.getApplySystemAll();
        } catch (Exception e) {
            logger.error("远程调用应用列表接口失败",e);
            return Result.fail("查询错误",null);
        }

        if (applySystemAll != null) {
            Object data = applySystemAll.getData();
            String s = JSON.toJSONString(data);
            List<String> strings = JSON.parseArray(s, String.class);
            applySystemAll.setData(strings);
            if (CollectionUtils.isEmpty(strings)) {
                return Result.fail("查询错误，未找到任何数据",null);
            }
        } else {
            logger.info("应用系统数据为空");
        }
        return Result.success("查询应用系统数据成功",applySystemAll.getData());
    }

    /**
     * 登录策略分页
     * @param imIdentApplyDto
     * @return
     */
    @RequestMapping("/getIamApplyPage")
    public Result<PageInfo<IamIdentApplyVo>> getIamApplyPage (@RequestBody IamIdentApplyDto imIdentApplyDto) {
        Result<PageInfo<IamIdentApplyVo>> iamApplyPage = identFeignInter.getIamApplyPage(imIdentApplyDto);
        Object data = iamApplyPage.getData();
        return Result.success("登录策略查询成功",data);
    }

    /**
     * sso登录搜索
     * @param applyTypeCode
     * @return
     */
    @RequestMapping("/getIamLoginStrategy")
    public Result<List<IamLoginStrategy>> getIamLoginStrategy (@RequestParam("applyTypeCode") String applyTypeCode,
                                                               HttpServletRequest request){
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        List<IamLoginStrategy> iamLoginStrategy =
                iamPasswordStrategyService.getIamLoginStrategy(applyTypeCode,companyCode);
        return Result.success("查询sso登录策略成功",iamLoginStrategy);
    }

    /**
     * sso登录配置
     * @param iamLoginStrategyDtos
     * @returne
     */
    @RequestMapping("/saveIamLoginStrategy")
    public Result saveIamLoginStrategy (@RequestBody List<IamLoginStrategyDto> iamLoginStrategyDtos,
                                        HttpServletRequest request) {
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        List<IamLoginStrategy> iamLoginStrategies =
                convertIamLoginStrategyList(iamLoginStrategyDtos, companyCode);
        int i = 0;
        try {
            i = iamPasswordStrategyService.saveIamLoginStrategy(iamLoginStrategies);
        } catch (Exception e) {
            return handleException(e,e.getMessage());
        }
        if (i == 0){
            return Result.success("新增登录策略未能更新成功", i);
        }
        return Result.success("新增登录策略更新成功", i);
    }

    /**
     * 异常登录策略分页
     * @param pageDto
     * @return
     */
    @RequestMapping("/getExceptionLoginStrategyPage")
    public Result<PageInfo<IamExceptionLoginStrategyVo>> getExceptionLoginStrategyPage (
            @RequestBody ExceptionLoginStrategyPageDto pageDto,HttpServletRequest request) {
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        PageInfo<IamExceptionLoginStrategyVo> exceptionLoginStrategyPage =
                iamExceptionLoginStrategyService.getExceptionLoginStrategyPage(pageDto,companyCode);
        return Result.success("异常登录分页查询成功",exceptionLoginStrategyPage);
    }

    /**
     * 异常登录策略新增
     * @param iamExceptionLoginStrategyDto
     * @return
     */
    @RequestMapping("/saveExceptionLoginStrategy")
    public Result saveExceptionLoginStrategy (@RequestBody IamExceptionLoginStrategyDto iamExceptionLoginStrategyDto,
                                              HttpServletRequest request){
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        IamExceptionLoginStrategy iamExceptionLoginStrategy =
                convertExceptionLoginStrategy(iamExceptionLoginStrategyDto,companyCode);
        int i = 0;
        try {
            //新增异常登陆策略
            i = iamExceptionLoginStrategyService.saveExceptionLoginStrategy(iamExceptionLoginStrategy);
        } catch (Exception e) {
            logger.error("新增异常登陆策略错误，信息为：{}", e);
            return handleException(e,e.getMessage());
        }
        if (i == 0){
            return Result.failWithMsg("未能成功新增异常登陆策略");
        }
        return  Result.success("新增异常登陆策略成功",i);
    }

    /**
     * 编辑异常登录策略
     * @param exceptionLoginStrategyDto
     * @return
     */
    @RequestMapping("/updateExceptionLoginStrategy")
    public Result updateExceptionLoginStrategy (@RequestBody IamExceptionLoginStrategyDto exceptionLoginStrategyDto,
                                                HttpServletRequest request){
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        IamExceptionLoginStrategy iamExceptionLoginStrategy =
                convertExceptionLoginStrategy(exceptionLoginStrategyDto,companyCode);
        int i = 0;
        try {
            //编辑策略
            i = iamExceptionLoginStrategyService.updateExceptionLoginStrategy(iamExceptionLoginStrategy);
        } catch (Exception e) {
            logger.error("更新异常登录策略错误，信息为：{}", e);
            return handleException(e,e.getMessage());
        }
        if (i == 0){
            return Result.failWithMsg("异常登录策略更新失败");
        }
        return Result.success("异常登录策略更新成功",i);
    }

    /**
     * 异常登录策略删除
     * @param list
     * @return
     */
    @RequestMapping("/deleteExceptionLoginStrategy")
    public Result deleteExceptionLoginStrategy (@RequestBody List<String> list,
                                                HttpServletRequest request) {
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }

        //批量删除策略
        int i = iamExceptionLoginStrategyService.deleteExceptionLoginStrategy(list,companyCode);
        if (i == 0){
            Result.failWithMsg("删除异常登录策策略失败");
        }
        return Result.success("删除异常登录策策略成功",i);
    }

    /**
     * 黑名单分页和搜索
     * @param pageDto
     * @return
     */
    @RequestMapping("/getBlacklistManagementPage")
    public Result<PageInfo<IamExceptionLoginStrategyVo>> getBlacklistManagementPage (
            @RequestBody BlacklistManagementPageDto pageDto) {

        PageInfo<IamBlacklistManagementVo> blacklistManagementPage =
                iamExceptionLoginStrategyService.getBlacklistManagementPage(pageDto);
        return Result.success("黑名单分页查询成功",blacklistManagementPage);
    }

    /**
     * 用户列表分页查询、搜索
     * @param userQueryParam
     * @return
     */
    @RequestMapping("/queryForUser")
    public Result<PageInfo<IamExceptionLoginStrategyVo>> queryForUser (
            @RequestBody UserQueryParam userQueryParam) {
        Result forUser = identFeignInter.queryUserNotOpen(userQueryParam);
        return Result.success("用户列表分页查询成功",forUser.getData());
    }

    /**
     * 新增黑名单
     * @param blacklistManagementDtos
     * @return
     */
    @RequestMapping("/saveBlacklistManagement")
    public Result saveBlacklistManagement (@RequestBody List<IamBlacklistManagementDto> blacklistManagementDtos){
        List<IamBlacklistManagement> list = new ArrayList<>();
        blacklistManagementDtos.forEach(blacklistManagementDto ->{
            IamBlacklistManagement blacklistManagement = new IamBlacklistManagement();
            BeanUtils.copyProperties(blacklistManagementDto,blacklistManagement);
            list.add(blacklistManagement);
        });
        int i = 0;
        try {
            //新增黑名单
            i = iamExceptionLoginStrategyService.saveBlacklistManagement(list);
        } catch (Exception e) {
            logger.error("新增黑名单错误，信息为：{}", e);
            return handleException(e,e.getMessage());
        }
        if (i == 0){
            return Result.failWithMsg("未能成功新增黑名单");
        }
        return  Result.success("新增黑名单成功",i);
    }

    /**
     * 删除/批量删除黑名单
     * @param list
     * @return
     */
    @RequestMapping("/deleteBlacklistManagement")
    public Result deleteBlacklistManagement (@RequestBody List<String> list) {
        //批量删除
        int i = iamExceptionLoginStrategyService.deleteBlacklistManagement(list);
        if (i == 0){
            Result.failWithMsg("删除黑名单失败");
        }
        return Result.success("删除黑名单成功",i);
    }

    /**
     * 多设备登录策略分页查询、搜索
     * @param pageDto
     * @return
     */
    @RequestMapping("/getIamMultiDeviceStrategyPage")
    public Result<PageInfo<IamMultideviceStrategyVo>> getIamMultiDeviceStrategyPage (
            @RequestBody IamMultiDeviceStrategyPageDto pageDto,HttpServletRequest request) {
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        PageInfo<IamMultideviceStrategyVo> iamMultiDeviceStrategyPage =
                iamMultiDeviceStrategyService.getIamMultiDeviceStrategyPage(pageDto,companyCode);
        return Result.success("多设备登录策略分页查询成功", iamMultiDeviceStrategyPage);
    }

    /**
     * 多设备登录策略新增
     * @param multideviceStrategyDto
     * @return
     */
    @RequestMapping("/saveIamMultiDeviceStrategy")
    public Result saveIamMultiDeviceStrategy (@RequestBody IamMultideviceStrategyDto multideviceStrategyDto,
                                              HttpServletRequest request){
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        IamMultideviceStrategy multiDeviceStrategy =
                convertIamMultideviceStrategy(multideviceStrategyDto,companyCode);
        int i = 0;
        try {
            //新增异常登陆策略
            i = iamMultiDeviceStrategyService.saveIamMultiDeviceStrategy(multiDeviceStrategy);
        } catch (Exception e) {
            logger.error("新增多设备登录策略错误，信息为：{}", e);
            return handleException(e,e.getMessage());
        }
        if (i == 0){
            return Result.failWithMsg("未能成功新增多设备登录策略");
        }
        return  Result.success("新增多设备登录策略成功",i);
    }

    /**
     * 编辑多设备登录策略
     * @param multiDeviceStrategyDto
     * @return
     */
    @RequestMapping("/updateIamMultiDeviceStrategy")
    public Result updateIamMultiDeviceStrategy (@RequestBody IamMultideviceStrategyDto multiDeviceStrategyDto,
                                                HttpServletRequest request){
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        IamMultideviceStrategy multiDeviceStrategy =
                convertIamMultideviceStrategy(multiDeviceStrategyDto,companyCode);
        int i = 0;
        try {
            //编辑策略
            i = iamMultiDeviceStrategyService.updateIamMultiDeviceStrategy(multiDeviceStrategy);
        } catch (Exception e) {
            logger.error("更新多设备登录策略错误，信息为：{}", e);
            return handleException(e,e.getMessage());
        }
        if (i == 0){
            return Result.failWithMsg("更新多设备登录策略更新失败");
        }
        return Result.success("多设备登录策略更新成功",i);
    }

    /**
     * 删除多设备登录策略
     * @param list
     * @return
     */
    @RequestMapping("/deleteIamMultiDeviceStrategy")
    public Result deleteIamMultiDeviceStrategy (@RequestBody List<String> list,
                                                HttpServletRequest request) {
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        //批量删除
        int i = iamMultiDeviceStrategyService.deleteIamMultiDeviceStrategy(list,companyCode);
        if (i == 0){
            Result.failWithMsg("删除多设备登录策略失败");
        }
        return Result.success("删除多设备登录策略",i);
    }

    /**
     * 查询当前用户所拥有的密码策略
     * @param request
     * @return
     */
    @RequestMapping("/queryApplyTypeCode")
    public Result<IamPasswordStrategyVo> queryApplyTypeCode (HttpServletRequest request) {
        String companyCode = request.getHeader(Constants.COMPANY_CODE);
        companyCode = "000001";
        if (StringUtils.isBlank(companyCode)) {
            throw new RuntimeException("当前归属租户状态异常！");
        }
        IamPasswordStrategyVo iamPasswordStrategyVo = null;
        try {
            String applyUrl = request.getHeader(Constants.APPLY_URL);
            IdentApplyTypeCodeDto identApplyTypeCodeDto = new IdentApplyTypeCodeDto();
            identApplyTypeCodeDto.setApplyUrl(applyUrl);
            Result result = identFeignInter.queryApplyTypeCode(identApplyTypeCodeDto);
            Object data = result.getData();
            String applyTypeCode = null;
            if (data != null) {
                applyTypeCode = data.toString();
            } else {
                throw new RuntimeException("根据Url查询到的应用类型为空，请检查url是否正确");
            }
            iamPasswordStrategyVo = iamPasswordStrategyService.queryPasswordStrategy(applyTypeCode,companyCode);
        } catch (Exception e) {
            logger.error("查询当前用户密码策略失败，信息为：{}", e);
            return handleException(e,e.getMessage());
        }

        return Result.success("查询当前用户密码策略成功",iamPasswordStrategyVo);
    }

    private IamMultideviceStrategy convertIamMultideviceStrategy (IamMultideviceStrategyDto multideviceStrategyDto,
                                                                  String companyCode) {
        IamMultideviceStrategy multideviceStrategy = new IamMultideviceStrategy();
        BeanUtils.copyProperties(multideviceStrategyDto,multideviceStrategy);
        multideviceStrategy.setCompanyCode(companyCode);
        return multideviceStrategy;
    }

    private IamExceptionLoginStrategy convertExceptionLoginStrategy (
            IamExceptionLoginStrategyDto exceptionLoginStrategyDto,String companyCode) {
        IamExceptionLoginStrategy exceptionLoginStrategy = new IamExceptionLoginStrategy();
        BeanUtils.copyProperties(exceptionLoginStrategyDto,exceptionLoginStrategy);
        exceptionLoginStrategy.setCompanyCode(companyCode);
        try {
            //异常登录开始时间
            exceptionLoginStrategy.setExceptionLoginStartTime(
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(
                            exceptionLoginStrategyDto.getExceptionLoginStartTime()));
            //异常登录结束时间
            exceptionLoginStrategy.setExceptionLoginEndTime(
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(
                            exceptionLoginStrategyDto.getExceptionLoginEndTime()));
        } catch (Exception e) {
            logger.info("method => convertExceptionLoginStrategy String类型转换Date错误{}",e);
        }

        return exceptionLoginStrategy;
    }

    /**
     * 登录策略dto转换entity
     * @param iamLoginStrategyDtoList
     * @return
     */
    private List<IamLoginStrategy> convertIamLoginStrategyList (List<IamLoginStrategyDto> iamLoginStrategyDtoList,
                                                                String companyCode){
        List<IamLoginStrategy> list = new ArrayList<>();
        iamLoginStrategyDtoList.forEach(iamLoginStrategyDto ->{
            IamLoginStrategy iamLoginStrategy = new IamLoginStrategy();
            BeanUtils.copyProperties(iamLoginStrategyDto,iamLoginStrategy);
            iamLoginStrategy.setCompanyCode(companyCode);
            list.add(iamLoginStrategy);
        });
        return list;
    }

    /**
     * 异常登录策略entity转vo
     * @param exceptionLoginStrategyList
     * @return
     */
    private List<IamExceptionLoginStrategyVo> convertExceptionLoginStrategyVo
    (List<IamExceptionLoginStrategy> exceptionLoginStrategyList){
        List<IamExceptionLoginStrategyVo> list = new ArrayList<>();
        exceptionLoginStrategyList.forEach(exceptionLoginStrategy ->{
            IamExceptionLoginStrategyVo exceptionLoginStrategyVo = new IamExceptionLoginStrategyVo();
            BeanUtils.copyProperties(exceptionLoginStrategy,exceptionLoginStrategyVo);
            list.add(exceptionLoginStrategyVo);
        });
        return list;
    }

}
